from msg_id import MsgId

### ------------------------------------- data struct ----------------------------------------###
class Map:
    x:int
    y:int
    viewport:dict
    
    def __init__(self):
        self.x = -1
        self.y = -1
        self.viewport = dict()
    
    def leave_map(self):
        self.x = -1
        self.y = -1

    def viewport_change(self, disappear, appear, move):
        for obj_dict in appear:
            uid = obj_dict['uid']
            x = obj_dict['x']
            y = obj_dict['y']
            self.viewport[uid] = (x, y)

        for obj_dict in disappear:
            uid = obj_dict['uid']
            if uid in self.viewport:
                self.viewport.pop(uid)
        
        for obj_dict in move:
            uid = obj_dict['uid']
            x = obj_dict['x']
            y = obj_dict['y']
            if uid in self.viewport:
                self.viewport[uid] = (x, y)
        



### ------------------------------------- base function --------------------------------------###
def mod_name():
    return __name__

def init_mod_data():
    return Map()

def registe_mod(player):
    player.data[mod_name()] = init_mod_data()

def get_data(player) -> Map:
    return player.data.get(mod_name(), Map())

def set_data(player, data:Map):
    player.data[mod_name()] = data    

def toc_handler(player, msg_id, content):
    if msg_id == MsgId.MSG_ID_ENTER_MAP.value:
        toc_enter_map(player, content)
    elif msg_id == MsgId.MSG_ID_LEAVE_MAP.value:
        toc_leave_map(player)
    elif msg_id == MsgId.MSG_ID_SYNC_MAP.value:
        pass;
    elif msg_id == MsgId.MSG_ID_VIEWPORT_CHANGE.value:
        toc_viewport_change(player, content)
    else:
        print(f'unmatch msg msg_id:{msg_id} content:{content}')

### ------------------------------------- mod function ---------------------------------------###
def set_pos(player, x, y):
    map = get_data(player)
    map.x = x
    map.y = y
    set_data(player, map)

### ------------------------------------- client to server -----------------------------------###
def tos_enter_map(player, x, y):
    msg = [('x', x), ('y', y)]
    player.send_msg(MsgId.MSG_ID_ENTER_MAP.value, msg)

def tos_leave_map(player):
    player.send_msg([])

def tos_sync_map(player, x, y):
    msg = [('x', x), ('y', y)]
    player.send_msg(MsgId.MSG_ID_SYNC_MAP.value, msg)
    set_pos(player, x, y)


### ------------------------------------- server to client -----------------------------------###
def toc_enter_map(player, content:dict):
    x = int(content.get('x', -1))
    y = int(content.get('y', -1))
    if x >= 0 and y >= 0:
        set_pos(player, x, y)

def toc_leave_map(player):
    map = get_data(player)
    map.leave_map()
    set_data(player, map)

def toc_viewport_change(player, content:dict):
    appear = content.get('appear', [])
    disappear = content.get('disappear', [])
    move = content.get('move', [])
    if appear != [] or disappear != [] or move != []:
        map = get_data(player)
        map.viewport_change(disappear, appear, move)
        set_data(player, map)

